#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct Node
{
    size_t value;
    struct Node *next;
    struct Node *prev;
}Node;

typedef struct 
{
    Node head;
    size_t len;
}List;

Node *node_init(int value)
{
    Node *node = (Node*)malloc(sizeof(Node));
    node->value = value;
    node->next = NULL;
    node->prev = NULL;

    return node;
}

void node_free(Node *node)
{
    if (node) free(node);
}

List *list_init()
{
    List *list = (List *)malloc(sizeof(List));
    list->head.next = NULL;
    list->head.prev = NULL;
    list->len = 0;
    
    return list;
}

void list_free(List *list)
{
    if (!list)
        return;
    Node *move = list->head.next;
    Node *record;

    while (move)
    {
        record = move;
        move = move->next;
        node_free(record);
    }
    
    free(list);

    return;
}

size_t node_insert(List *list, size_t idx, Node *node)
{

    if (!node)
        return 0;

    if (idx < 0 || idx > list->len)
        return 0;
    
    Node *move_node = &(list->head);

    while (idx--)
    {
        move_node = move_node->next;
    }
    
    node->next = move_node->next;
    move_node->next = node;
    node->prev = move_node;
    if (node->next)
    {
        node->next->prev = node;
    }
    

    list->len++;
    
    return 1;
}


size_t value_insert(List *list, size_t idx ,size_t value)
{
    Node *node = node_init(value);

    if (!node_insert(list, idx, node))
    {
        node_free(node);
        return 0;
    }

    return 1;
}

size_t node_delete(List *list, size_t idx)
{
    if(!list)
        return 0;
    
    if (idx < 0 || idx >= list->len)
        return 0;
    
    Node *move_node = &(list->head);
    Node *record;
    
    while (idx--)
    {
        move_node = move_node->next;
    }

    record = move_node->next;
    move_node->next = record->next;

    if (record->next)
    {
        record->next->prev = move_node;
    }
    
    node_free(record);
    list->len--;

    return 1;
}

void show_list_val(List *list)
{
    if (!list)
        return;
    
    Node *move_node = list->head.next;
    Node *record = &(list->head);

    printf("List+:[");
    while (move_node)
    {
        record = move_node;
        printf("%ld->",move_node->value);
        move_node = move_node->next;
    }
    printf("NULL]\n");
    
    printf("List-:[");
    while (record != &(list->head))
    {
        printf("%ld->",record->value);
        record = record->prev;
    }
    printf("HEAD]\n");
}

// 翻转链表
size_t list_reverse(List *list)
{
    if (!list)
        return 0;
    
    Node *node = list->head.next;
    Node *record;

    list->head.next = NULL;
    list->len = 0;

    while (node)
    {
        record = node;
        node = node->next;

        node_insert(list, 0, record);
    }
    
    return 1;
}

int main(void)
{
    List *list = list_init();

    srand(time(0));

    int cnt = 20;

    while (cnt--)
    {
        size_t val = rand() % 100;
        size_t op = rand() % 5;
        size_t idx = rand() % (list->len + 3) - 1;

        switch (op)
        {
        case 0:
        case 1:
        case 2:
            printf("insert %ld at %ld, res = %s.\n", val, idx, value_insert(list, idx, val) ? "SUC":"ERR");
            break;
        case 3:
            printf("delete at %ld, res = %s.\n", idx, node_delete(list, idx) ? "SUC":"ERR");
            break;
        case 4:
            printf("reverse res = %s.\n", list_reverse(list) ? "SUC":"ERR");
            break;
        default:
            break;
        }

        show_list_val(list);
    }

    list_free(list);
    return 0;
}